package estadistec.logica.parser;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileWriter;

import estadistec.logica.tabla.LTabla;
import estadistec.logica.tipos.TipoValor;
import java.util.ArrayList;



/**
 * Esta clase encapsula la funcionalidad de este package, se encarga de llamar
 * al parser con la entrada indicada al inicializar.
 */
public class Parser
{
	private DataObject obj;
	private EstructuraEvaluable ee;
	private ArrayList<IEvaluable> depende;
	private LTabla tabla;
	private String ARCH_TEMP = new String("Archivo_temporal_estadistec");
	private static boolean _inicializado = false;
	private Identificador parser;
	
	/**
	 *@param tabla tabla lógica a la que estará asociado este objeto, la cual será
	 *  usada a la hora de la evaluación
	 */
	public Parser(LTabla tabla)
	{
		this.obj = null;
		this.ee = null;
		this.tabla = tabla;
		this.depende = null;
	}
	
	
	/**
	 * Inicializa este objeto parser, asignándole un comando dado por el usuario,
	 * el cual va a ser utilizado para su posterior evaluación.
	 */
	public void inicializar(String comando) throws ParseException
	{
		try{
			obj = null;
			
			FileWriter fw = new FileWriter(ARCH_TEMP);
			fw.write(comando);
			fw.flush();
			fw.close();

			FileInputStream fis = new FileInputStream(ARCH_TEMP);
			InputStream is = (InputStream) fis;

			if (!_inicializado) 
				parser = new Identificador(is);
			else
				parser.ReInit(is);
			obj = parser.Start();
		
			_inicializado = true;
			fis.close();
			File f = new File(ARCH_TEMP);
			f.delete();
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
	}
	
	
	/**
	 * Devulve el tipo resultante de evaluar el comando indicado
	 * a la hora en que este objeto fue inicializado.
	 * @return El tipo resultante de la evaluación del comando actual de este objeto,
	 *   si no se ha inicializado retorna {@code null}
	 */
	public TipoValor getTipo()
	{
		if(!_inicializado)
			return null;
		switch(obj.getTipo(this.tabla))
		{
			case BOOL:
			case LISTA_BOOL:
				return TipoValor.BOOLEANO;
			case ENTERO:
			case LISTA_ENTERO:
				return TipoValor.ENTERO;
			case FLOTANTE:
			case LISTA_FLOTANTE:
				return TipoValor.FLOTANTE;
			case CUALITATIVO:
			case LISTA_CUALITATIVO:
				return TipoValor.CUALITATIVO;
			case RANGO:
			case LISTA_RANGO:
				return TipoValor.INTERVALO;
		}
		return null;
	}
	
	
	/**
	 * Da una estructura capaz de evaluar el comando, corresponde al último proceso de la 
	 * etapa del parser.
	 * @return Una estructura que se sabe evaluar el comando actual de este objeto,
	 *   si no se ha inicializado retorna {@code null}
	 */
	public EstructuraEvaluable getEstructura()
	{
		if(!_inicializado) return null;
		this.depende = new ArrayList<IEvaluable> ();
		return this.obj.getEstructuraEvaluable(this.tabla, depende);
	}

	/**
	 * Da los superiores de los cuales depende esta fórmula al ser evaluada
	 * @return La lista de los IEvaluables de los cuales depende esta fórmula
	 */
	public ArrayList<IEvaluable> getListaSuperiores()
	{
		return this.depende;
	}
	
	
}



